﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PocketBook.UI.View;
using PocketBook.Domain.Entities;
using PocketBook.UI.ViewModel.Workspaces;
using PocketBook.Domain.Abstract;
using PocketBook.Domain.Concrete;
using GalaSoft.MvvmLight.Command;
using System.ComponentModel;
using PocketBook.UI.Model;

namespace PocketBook.UI.ViewModel.Dialogs
{
    public class AddOrUpdateExpenseViewModel : BaseDialogViewModel, IDataErrorInfo
    {
        private ExpensesWorkspaceViewModel _parent;
        private IModelFactory _model;
        private Guid _id;
        private PocketBookDialog _window;

        #region Constructor

        public AddOrUpdateExpenseViewModel(PocketBookDialog window, ExpensesWorkspaceViewModel parent, Expense expense = null)
            : base(window)
        {
            _parent = parent;
            _model = ViewModelLocator.Kernel.Get<ModelFactory>();
            _window = window;
            if (expense != null)
            {
                base.DisplayName = "Edit expense";
                Name = expense.Name;
                Amount = expense.Amount;
                Description = expense.Description;
                _id = expense.ExpenseId;
            }
            else
            {
                base.DisplayName = "Add expense";
                _id = Guid.NewGuid();
            }
        }

        #endregion

        #region Fields

        private const string NamePropertyName = "Name";
        private string _name;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (_name == value)
                {
                    return;
                }
                _name = value;
                RaisePropertyChanged(NamePropertyName);
            }
        }

        private const string AmountPropertyName = "Amount";
        private decimal _amount;

        public decimal Amount
        {
            get
            {
                return _amount;
            }
            set
            {
                if (_amount == value)
                {
                    return;
                }
                _amount = value;
                RaisePropertyChanged(AmountPropertyName);
            }
        }

        private const string DescriptionPropertyName = "Description";
        private string _description;

        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                if (_description == value)
                {
                    return;
                }
                _description = value;
                RaisePropertyChanged(DescriptionPropertyName);
            }
        }

        #endregion

        #region Commands

        private RelayCommand _saveCommand;
        public RelayCommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new RelayCommand(() => this.Save(), () => IsValid);
                }
                return _saveCommand;
            }
        }

        #endregion

        #region Private Helpers

        private void Save()
        {
            _model.AddOrUpadateExpense(_parent,
                new Expense 
                { 
                    ExpenseId = _id,
                    Name = _name,
                    Amount = _amount,
                    Description = _description
                });
            _window.Close();
        }

        #endregion

        #region VALIDATION
        static readonly string[] ValidateProperties =
        {
            AmountPropertyName
        };

        protected string Validate(string propertyName)
        {
            string validationResult = null;
            switch (propertyName)
            {
                case AmountPropertyName:
                    if (Amount == 0)
                    {
                        validationResult = "Error";
                    }
                    break;
                default:
                    throw new ApplicationException("Unknown Property being validated on TextBoxControlViewModel.");
            }
            return validationResult;
        }

        public bool IsValid
        {
            get
            {
                foreach (var item in ValidateProperties)
                {
                    if (!string.IsNullOrEmpty(Validate(item)))
                    {
                        return false;
                    }
                }
                return true;
            }
        }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        public string this[string propertyName]
        {
            get
            {
                return Validate(propertyName);
            }
        }
        #endregion
    }
}
